<?php
namespace app\common\model;

use think\Model;

class UserWallet extends Model {
    
    /**
     * 定义主键
     * @var string
     */
    protected $pk = 'uw_wallet_id';
    
    /**
     * @desc 钱包类型
     * @var array
     */
    protected $_walletType = [
        USER_RECHARGE_WALLET => '充值钱包',
        USER_INCOME_WALLET   => '收益钱包',
    ];
    
    /**
     * 初始化钱包数据
     * @param int $userId
     * @param int $walletType 1.充值钱包 2-收益钱包
     * @return array|bool|\PDOStatement|string|Model|null
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function initWallet($userId, $walletType) {
        $where = [
            ['uw_user_id', '=', $userId],
            ['uw_wallet_type', '=', $walletType]
        ];
        $field = [
            'uw_wallet_id AS walletId',
            'uw_balance AS balance',
            'uw_freeze_balance AS freezeBalance'
        ];
        $walletData = $this->field($field)->where($where)->find();
        if(!$walletData) {
            $walletId = $this->where($where)->insertGetId([
                'uw_user_id'     => $userId,
                'uw_wallet_type' => $walletType,
                'uw_remark'      => $this->_walletType[$walletType],
                'uw_modify_time' => date('Y-m-d H:i:s'),
                'uw_create_time' => date('Y-m-d H:i:s'),
            ]);
            $walletData = $this->field($field)->where('uw_wallet_id', '=', $walletId)->find();
        }
        return $walletData;
    }
    
    
    /**
     * @desc 获取账号余额
     * @rule 钱包余额 - 冻结余额 = 实际可用余额
     * @param int $userId
     * @param int $walletType
     * @return string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function getBalance($userId, $walletType = USER_RECHARGE_WALLET) {
        $walletInfo = $this->initWallet($userId, $walletType);
        return bcsub($walletInfo['balance'], $walletInfo['freezeBalance'], 2);
    }
    
    /**
     * 统计用户所有钱包可用余额
     * @param int $userId 用户ID
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function userAllWallet($userId){
        $rechargeWallet = $this->getBalance($userId , USER_RECHARGE_WALLET ); //充值钱包
        $incomeWallet = $this->getBalance($userId , USER_INCOME_WALLET ); //收益钱包
        return [
            'rechargeWallet' => $rechargeWallet,
            'incomeWallet'   => $incomeWallet
        ];
    }
    
    /**
     * @desc 冻结金额
     * @param int $userId 用户ID
     * @param int $walletType 用户钱包类型
     * @param float $balance 冻结金额
     * @param string $detail 详情
     * @param string $remark 备注
     * @return int|string
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public function freezeBalance($userId, $walletType, $balance, $detail, $remark) {
        $walletInfo = $this->initWallet($userId, $walletType);
        
        //增加冻结金额
        $this->where('uw_wallet_id', '=', $walletInfo['walletId'])
            ->setInc('uw_freeze_balance', $balance);
        
        //生成冻结记录
        $freezeId = model('FreezeRecord')->insertGetId([
            'ar_wallet_id'   => $walletInfo['walletId'],
            'ar_detail'      => $detail,
            'ar_amount'      => $balance,
            'ar_status'      => FREEZE_RECORD_STATUS_FREEZE,
            'ar_remark'      => $remark,
            'ar_modify_time' => date('Y-m-d H:i:s'),
            'ar_create_time' => date('Y-m-d H:i:s')
        ]);
        return $freezeId;
    }
    
    /**
     * @desc 解冻金额
     * @param $freezeId
     * @return int|string
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public function unfreezeBalance($freezeId) {
        $field = [
            'ar_freeze_id AS freezeId',
            'ar_wallet_id AS walletId',
            'ar_amount AS amount',
            'ar_status AS status',
        ];
        $freezeRecordInfo = model('FreezeRecord')
            ->field($field)
            ->where('ar_freeze_id', '=', $freezeId)
            ->find();
        
        //减少冻结金额
        $this->where('uw_wallet_id', '=', $freezeRecordInfo['walletId'])
            ->setDec('uw_freeze_balance', $freezeRecordInfo['amount']);
        
        //记录解冻
        $result = model('FreezeRecord')
            ->where('ar_freeze_id', '=', $freezeId)
            ->update([
                'ar_status'      => FREEZE_RECORD_STATUS_UNFREEZE,
                'ar_modify_time' => date('Y-m-d H:i:s')
            ]);
        return $result;
    }
    
    /**
     * @desc 扣除金额
     * @rule userId = 0 代表系统
     * @param int $userId 用户ID
     * @param int $walletType 钱包类型
     * @param float $amount 扣除余额
     * @param string $detail 详细信息
     * @param string $remark 备注
     * @return int|string
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public function decBalance($userId, $walletType, $amount, $detail, $remark) {
        $walletInfo = $this->initWallet($userId, $walletType);
        
        //减去用户金额
        $this->where('uw_wallet_id', '=', $walletInfo['walletId'])
            ->setDec('uw_balance', $amount);
        
        //生成金流记录
        $result = model('AccountRecord')->insert([
            'ar_from_user_id'  => $userId, //出账userID
            'ar_to_user_id'    => 0, //入账UserID，0代表系统
            'ar_amount'        => $amount,
            'ar_before_amount' => $walletInfo['balance'],
            'ar_after_amount'  => bcsub($walletInfo['balance'], $amount, 2),
            'ar_detail'        => $detail,
            'ar_remark'        => $remark,
            'ar_modify_time'   => date('Y-m-d H:i:s'),
            'ar_create_time'   => date('Y-m-d H:i:s'),
        ]);
        return $result;
    }
    
    /**
     * @desc 增加金额
     * @rule userId = 0 代表系统用户
     * @param int $userId 用户ID
     * @param int $walletType 钱包类型
     * @param float $amount 扣除余额
     * @param string $detail 详细信息
     * @param string $remark 备注
     * @return int|string
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public function incBalance($userId, $walletType, $amount, $detail, $remark) {
        $walletInfo = $this->initWallet($userId, $walletType);
        
        //增加金额
        $this->where('uw_wallet_id', '=', $walletInfo['walletId'])
            ->setInc('uw_balance', $amount);
        
        //生成金流记录
        $result = model('AccountRecord')->insert([
            'ar_from_user_id'  => 0, //出账userID
            'ar_to_user_id'    => $userId, //入账UserID，0代表系统
            'ar_amount'        => $amount,
            'ar_before_amount' => $walletInfo['balance'],
            'ar_after_amount'  => bcadd($walletInfo['balance'], $amount, 2),
            'ar_detail'        => $detail,
            'ar_remark'        => $remark ?: '',
            'ar_modify_time'   => date('Y-m-d H:i:s'),
            'ar_create_time'   => date('Y-m-d H:i:s'),
        ]);
        return $result;
    }
}